// -*- c++ -*-
/**************************************************************/
/*  This file is licensed from, and is a trade secret of:     */
/*                                                            */
/*    Mercury Computer Systems, Incorporated                  */
/*    199 Riverneck Road                                      */
/*    Chelmsford, Massachusetts 01824-2820                    */
/*    United States of America                                */
/*    Telephone + 1 978 256-1300                              */
/*                                                            */
/*  Refer to your Software License Agreement for provisions   */
/*  on use, duplication, or disclosure.                       */
/*  US. Government users and prime contractors are also       */
/*  governed by the following Data Rights Notice:             */
/*  Use, duplication or disclosure by the US. Government is   */
/*  subject to the provisions set forth in FAR 52.227-14 for  */
/*  restricted rights or other agency data rights provisions  */
/*  on commercial software and documentation, as applicable.  */
/*                                                            */
/*  This file: (a) was developed at private expense, and no   */
/*  part was developed with government funds, (b) is a        */
/*  trade secret of Mercury Computer Systems, Inc. for the    */
/*  purposes of the Freedom of Information Act, (c) is        */
/*  "commercial computer software" subject to limited         */
/*  utilization as provided in the above noted Software       */
/*  License Agreement and (d) is in all respects data         */
/*  belonging exclusively to Mercury Computer Systems, Inc..  */
/*                                                            */
/**************************************************************/

/******************************************************************/
/* Copyright (c) 1999-2003, Mercury Computer Systems, Inc.,       */
/* Chelmsford MA.,and all third party embedded software sources.  */
/* All rights reserved under the Copyright laws of US. and        */
/* international treaties.                                        */
/*                                                                */
/* Patent Pending                                                 */
/******************************************************************/


//$COPYRIGHT_END


#ifndef CVSD_H__
#define CVSD_H__

#include <vector>
#include <fstream>

#include "CF__Resource_impl.h"
#include "AudioPort_impl.h"
#include "SceOsThreadManager.h"
#include "mc_error.h"
#include "LogServiceC.h"

// Forward declaration.
class CVSDEncoderLogPort;

typedef std::vector<double> FVector;
typedef std::vector<long>  LVector;
typedef FVector::iterator FVecIt;
typedef LVector::iterator LVecIt;

// Bit Manipulation helpers.
#define CBIT(w, b)	((w) &= ~(0x01 << (b)))
#define SBIT(w, b)	((w) |= (0x01 << (b)))
#define TBIT(w, b)	((((w) >> (b)) & 0x01) ? 1 : 0)

#ifdef _WIN32
#ifndef CVSD_EXPORTS
#define CVSD_EXPORT __declspec(dllimport)
#else 
#define CVSD_EXPORT __declspec(dllexport)
#endif
#else //_WIN32
#define CVSD_EXPORT
#endif // _WIN32

class CVSD_EXPORT CVSD : public CF__Resource_impl
{
public:
  virtual ~CVSD();

protected:
  CVSD(const char *identifier);
  status Init ();

  // Inner loop method that performs component business logic.
  virtual status Run () = 0;
  // Separate thread master function	
  static void RunWorker (void * param);
  // Inner loop function that deals with external commands.
  virtual void RunLoop () = 0;

  double m_fAverageRMS;
  int m_iOldbits;

  double m_fOld_avg_delta;
  double m_fOld_cvsd_ref;

  short * m_vlPCMData;  // decoded/filtered PCM data
  float * m_vfPCMData;  // PCM data through AGC before encoding
  char * m_vlCVSDData;  // encoded data bits
  float * m_vfCVSDData; // filtered data after decoding

  int m_input_count;

  static const double m_coCoef[51];

  static const double DA_MAX;
  static const double AD_MAX;
  static const double CVSD_STEP_MAX;
  static const double CVSD_STEP_MIN;
  static const double CVSD_DELTA_TC;
  static const double CVSD_REF_TC;
  static const double ATTACK_AGC_TC;

  static const double RELEASE_AGC_TC;
  static const double MAX_AGC_RANGE;

  static const int FRAME_BLK_SIZE;
  static const int FILTER_LENGTH;

  bool  m_bStop;
  int   m_iLineNumber;

  SCE::OS::ThreadManager m_thread;
  bool m_threadrunning;
};

class CVSD_EXPORT CVSDEncoder : public CVSD {
public:
  static status Create(CVSDEncoder *& CvsdHandle, const char *identifier);

  // Inner loop method that performs component business logic
  virtual status Run ();
  // Inner loop function that deals with external commands
  virtual void RunLoop ();

  // From CF::Resource
  virtual void start ()
    throw (CORBA::SystemException, CF::Resource::StartError);
  virtual void stop ()
    throw (CORBA::SystemException, CF::Resource::StopError);

  // From CF::PortSupplier
  virtual CORBA::Object_ptr getPort (const CORBA::Char* name)
    throw (CORBA::SystemException, CF::PortSupplier::UnknownPort);

  virtual ~CVSDEncoder ();

  // Function to configure the Log Service.
  virtual status setLogObject (CORBA::Object_ptr logObject);

private:
  CVSDEncoder (const char *identifier);
  status Init ();

  void ConvertToCVSD (int length);
  void AutomaticGainControl (int length);
  void Encode (int length);

  PcmInPort_impl *m_pcmin;
  CvsdOutPort_impl *m_cvsdout;

  LogService::Log_var m_log;
  CVSDEncoderLogPort * m_logportservant;
  CF::Port_var m_logport;
};

class CVSD_EXPORT CVSDDecoder: public CVSD {
public:
  static status Create (CVSDDecoder *& DecoderHandle, const char *identifier);

  // Inner loop method that performs component business logic
  virtual status Run ();
  // Inner loop function that deals with external commands
  virtual void RunLoop();

  // From CF::Resource
  virtual void start ()
    throw (CORBA::SystemException, CF::Resource::StartError);
  virtual void stop ()
    throw (CORBA::SystemException, CF::Resource::StopError);

  // From CF::PortSupplier
  virtual CORBA::Object_ptr getPort(const CORBA::Char* name)
    throw (CORBA::SystemException, CF::PortSupplier::UnknownPort);

  virtual ~CVSDDecoder ();

private:
  CVSDDecoder (const char *identifier);
  status Init ();

  void ConvertToPCM (int length);

  void Decode (int length);
  void LowPassFilter (int length);

  CvsdInPort_impl *m_cvsdin;
  PcmOutPort_impl *m_pcmout;
};

class CVSD_EXPORT CVSDEncoderLogPort
  : virtual public POA_CF::Port,
    virtual public PortableServer::RefCountServantBase
{
public:
  CVSDEncoderLogPort (CVSDEncoder* parent);
  ~CVSDEncoderLogPort ();

  virtual void connectPort (CORBA::Object_ptr connection,
			    const CORBA::Char * connectionId)
    throw (CORBA::SystemException,
	   ::CF::Port::InvalidPort,
	   ::CF::Port::OccupiedPort);
  virtual void disconnectPort (const CORBA::Char * connectionId)
    throw (CORBA::SystemException,
	   ::CF::Port::InvalidPort);

protected:
  CORBA::String_var m_connectionId;
  CVSDEncoder * m_parentComponent;
};

#endif // CVSD_H__
